#!/usr/bin/env python

########################################################################
#                                                                      #
#               This software is part of the ECharts package           #
#                  Copyright (c) 2006-2007 AT&T Corp.                  #
#                      and is licensed under the                       #
#                  Common Public License, Version 1.0                  #
#                            by AT&T Corp.                             #
#                                                                      #
########################################################################


import sys
import os, os.path
import stat
import string
import datetime
import shutil
import findfiles
import versioncheck

import templates.build_xml
import templates.build_properties
import templates.env_properties
import templates.sip_xml_b2bua
import templates.sip_xml_proxy
import templates.web_xml
import templates.sample_ech
import templates.sample_proxy
import templates.dot_project
import templates.dot_sip_project
import templates.dot_classpath
import templates.dot_echartspath
import templates.skeleton_test
import templates.skeleton_test_runner
import templates.test_sip_xml_b2bua
import templates.test_sip_xml_proxy
import templates.test_web_xml
import templates.test_build_xml
import templates.test_build_properties
import templates.test_properties

srcDir = 'src'

def package2dir(package):
	return os.sep.join(package.split('.'))

def createFileFromTemplate(fileName, template, vars={}):
	contents = template.getTemplate() % vars
	fd = open(fileName, 'w')
	fd.write(contents)
	fd.close()

def createDirDuplicateOK(dirName):
	try:
		os.makedirs(dirName)
	except OSError, (errno, strerror):
        # Check for "directory already exists" error
        # errno = 17 on Un*x, errno = 183 on Windows
        #
		if errno == 17 or errno == 183:
			# dir already exists, that's fine
			#
			pass
		else:
			# re-raise error
			#
			raise

def createMachine(appPackage, targetDir, appName, className, templateVars):
	if appPackage != None and len(appPackage) > 0:
		pdir = package2dir(appPackage)
	else:
		pdir = appName
	dirName = targetDir + os.sep + srcDir + os.sep + pdir
	createDirDuplicateOK(dirName)
	
	fileName = dirName + os.sep + className + '.ech'
	createFileFromTemplate(fileName, templates.sample_ech, templateVars)

def createProxy(appPackage, targetDir, appName, className, templateVars):
	if appPackage != None and len(appPackage) > 0:
		pdir = package2dir(appPackage)
	else:
		pdir = appName
	dirName = targetDir + os.sep + srcDir + os.sep + pdir
	createDirDuplicateOK(dirName)
	
	fileName = dirName + os.sep + className + '.java'
	createFileFromTemplate(fileName, templates.sample_proxy, templateVars)

def createTestSkeleton(templateVars):
	if templateVars['appTestPackage'] != None and len(templateVars['appTestPackage']) > 0:
		pdir = package2dir(templateVars['appTestPackage'])
	else:
		pdir = templateVars['appTest']
	dirName = templateVars['targetDir'] + os.sep + "test" + os.sep + "src" + os.sep + "testcases" + os.sep + pdir
	fileName = dirName + os.sep + templateVars['classTestName'] + '.java'
	createFileFromTemplate(fileName, templates.skeleton_test, templateVars)

def createTestRunner(templateVars):
	dirName = templateVars['targetDir'] + os.sep + "test"
	fileName = dirName + os.sep + "runtest.sh" 
	createFileFromTemplate(fileName, templates.skeleton_test_runner, templateVars)
	os.chmod(fileName, stat.S_IRWXU)

def createTopLevelREADMEs(targetDir):
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "lib-README.txt", targetDir + os.sep + "lib" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "ech-README.txt", targetDir + os.sep + "ech" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "ech_java-README.txt", targetDir + os.sep + "ech_java" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "src-README.txt", targetDir + os.sep + "src" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "doc-README.txt", targetDir + os.sep + "doc" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "SarContent_WEB-INF_lib-README.txt", targetDir + os.sep + "SarContent" + os.sep + "WEB-INF" + os.sep + "lib" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "SarContent_WEB-INF_classes-README.txt", targetDir + os.sep + "SarContent" + os.sep + "WEB-INF" + os.sep + "classes" + os.sep + "README.txt")

def createTestLevelREADMEs(targetDir):
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "test-README.txt", targetDir + os.sep + "test" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "test-lib-README.txt", targetDir + os.sep + "test" + os.sep + "lib" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "ech_java-README.txt", targetDir + os.sep + "test" + os.sep + "ech_java" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "test-build-README.txt", targetDir + os.sep + "test" + os.sep + "build" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "test-resources-README.txt", targetDir + os.sep + "test" + os.sep + "resources" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "test-src-README.txt", targetDir + os.sep + "test" + os.sep + "src" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "doc-README.txt", targetDir + os.sep + "test" + os.sep + "doc" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "SarContent_WEB-INF_lib-README.txt", targetDir + os.sep + "test" + os.sep + "SarContent" + os.sep + "WEB-INF" + os.sep + "lib" + os.sep + "README.txt")
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "SarContent_WEB-INF_classes-README.txt", targetDir + os.sep + "test" + os.sep + "SarContent" + os.sep + "WEB-INF" + os.sep + "classes" + os.sep + "README.txt")

def createTopLevelSipXML(templateVars, appType):
	webInfDir = templateVars['targetDir'] + os.sep + 'SarContent' + os.sep + 'WEB-INF'
	createDirDuplicateOK(webInfDir)
	if appType == "b2bua":
		createFileFromTemplate(webInfDir + os.sep + 'sip.xml', templates.sip_xml_b2bua, templateVars)
	else:
		createFileFromTemplate(webInfDir + os.sep + 'sip.xml', templates.sip_xml_proxy, templateVars)
		
def createTestLevelSipXML(templateVars, appType):
	webInfDir = templateVars['targetDir'] + os.sep + "test" + os.sep + 'SarContent' + os.sep + 'WEB-INF'
	createDirDuplicateOK(webInfDir)
	if appType == "b2bua":
		createFileFromTemplate(webInfDir + os.sep + 'sip.xml', templates.test_sip_xml_b2bua, templateVars)
	else:
		createFileFromTemplate(webInfDir + os.sep + 'sip.xml', templates.test_sip_xml_proxy, templateVars)
		
def createTopLevelWebXML(templateVars):
	webInfDir = templateVars['targetDir'] + os.sep + 'SarContent' + os.sep + 'WEB-INF'
	createDirDuplicateOK(webInfDir)
	createFileFromTemplate(webInfDir + os.sep + 'web.xml', templates.web_xml, templateVars)

def createTestLevelWebXML(templateVars):
	webInfDir = templateVars['targetDir'] + os.sep + "test" + os.sep + 'SarContent' + os.sep + 'WEB-INF'
	createDirDuplicateOK(webInfDir)
	createFileFromTemplate(webInfDir + os.sep + 'web.xml', templates.test_web_xml, templateVars)

def createTopLevelBuildXML(templateVars):
	createFileFromTemplate(templateVars['targetDir'] + os.sep + 'build.xml', templates.build_xml, templateVars)

def createTestLevelBuildXML(templateVars):
	createFileFromTemplate(templateVars['targetDir'] + os.sep + 'test' + os.sep + 'build.xml', templates.test_build_xml, templateVars)

def createTopLevelBuildProperties(templateVars):
	createFileFromTemplate(templateVars['targetDir'] + os.sep + 'build.properties', templates.build_properties, templateVars)

def createTestLevelBuildProperties(templateVars):
	createFileFromTemplate(templateVars['targetDir'] + os.sep + 'test' + os.sep + 'build.properties', templates.test_build_properties, templateVars)

def createTopLevelEclipseFiles(templateVars):
	createFileFromTemplate(templateVars['targetDir'] + os.sep + '.project', templates.dot_project, templateVars)
	createFileFromTemplate(templateVars['targetDir'] + os.sep + '.sip_project', templates.dot_sip_project, templateVars)
	createFileFromTemplate(templateVars['targetDir'] + os.sep + '.classpath', templates.dot_classpath, templateVars)
	createFileFromTemplate(templateVars['targetDir'] + os.sep + '.echartspath', templates.dot_echartspath, templateVars)

def createTopLevelEnvProperties(templateVars):
	createFileFromTemplate(templateVars['targetDir'] + os.sep + 'env.properties', templates.env_properties, templateVars)

def createTestLevelEnvProperties(templateVars):
	createFileFromTemplate(templateVars['targetDir'] + os.sep + 'test' + os.sep + 'env.properties', templates.env_properties, templateVars)

def createTestLevelLog4jProperties(templateVars):
	shutil.copyfile(appgen_home + os.sep + 'files' + os.sep + "test_log4j.properties", templateVars['targetDir'] + os.sep + "test" + os.sep + "log4j.properties")

def createTestLevelTestProperties(vars):
	createFileFromTemplate(vars['targetDir'] + os.sep + 'test' + os.sep + 'test.properties', templates.test_properties, vars)

def getNamesFromUser(edk_home):
	try:
		print "SIP ECharts APPLICATION CREATION WIZARD (modified for the Telcoblocks Project by GSI-DIT ETSIT-UPM)"
		targetDir=sys.argv[1]
		appType=sys.argv[2] #Application type: b2bua or proxy
		appPackage=sys.argv[3] # Fully-qualified package name (E.g com.example.sipecharts.myApp)
		lastDot = appPackage.rfind('.')

		if lastDot == -1:
			appName = appPackage
		else:
			appName = appPackage[lastDot+1:]

		className = sys.argv[4] # Class name for proxy application or main Machine (in case of b2bua projects)

		if len(className) == 0:
			raise ValueError, "Must specify class name"

		if appType == 'b2bua' and edk_home != None:
			# check classname for collisions with machine classes in EDK
			echfiles = findfiles.findfiles(edk_home, 'ech', strip_extension=1)
			if className in echfiles:
				print "ERROR: This classname already exists under EDK_HOME."
				print "Choose another class name."
				sys.exit(1)

		javadocTitle = sys.argv[5] #Application title (for Javadocs/display-name)

		if len(javadocTitle) == 0:
			raise ValueError, "Must specify title"

		return {'targetDir':targetDir, 'appType':appType, 'appPackage':appPackage, 'appName':appName, 'className':className, 'javadocTitle':javadocTitle}

	except (EOFError, KeyboardInterrupt):
		print "Exiting"
		sys.exit(1)

def createTopLevelDirectories(targetDir):
	createDirDuplicateOK(targetDir)	
	createDirDuplicateOK(targetDir + os.sep + "lib")	
	createDirDuplicateOK(targetDir + os.sep + "doc")
	createDirDuplicateOK(targetDir + os.sep + "SarContent" + os.sep + "WEB-INF" + os.sep + "lib")
	createDirDuplicateOK(targetDir + os.sep + "SarContent" + os.sep + "WEB-INF" + os.sep + "classes")
	createDirDuplicateOK(targetDir + os.sep + "ech")
	createDirDuplicateOK(targetDir + os.sep + "ech_java")
	createDirDuplicateOK(targetDir + os.sep + "test")

def createTestLevelDirectories(vars):
	if vars['appTestPackage'] != None and len(vars['appTestPackage']) > 0:
		pdir = package2dir(vars['appTestPackage'])
	else:
		pdir = vars['appTestName']
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "src" + os.sep + "testcases" + os.sep + pdir)	
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "src" + os.sep + "testharness" + os.sep + pdir)	
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "lib")	
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "doc")
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "SarContent" + os.sep + "WEB-INF" + os.sep + "lib")
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "SarContent" + os.sep + "WEB-INF" + os.sep + "classes")
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "ech_java")
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "build")
	createDirDuplicateOK(vars['targetDir'] + os.sep + "test" + os.sep + "resources")

def createSourceTree(targetDir, appType, appPackage, appName, className, javadocTitle):

	vars = {
		'targetDir': targetDir,
		'appPackage': appPackage,
		'appName': appName,
		'className': className,
		'javadocTitle': javadocTitle,
		'currentYear': datetime.date.today().year,
		'appTestPackage': appPackage + ".test",
		'appTestName': appName + "Test",
		'classTestName': className + "Test"		
		}

	print
	print "Creating source tree ..."

	createTopLevelDirectories(targetDir)

	if appType == 'b2bua':
		createMachine(appPackage, targetDir, appName, className, vars)
	else:
		createProxy(appPackage, targetDir, className, vars)

	# print "Creating sip.xml ..."
	createTopLevelSipXML(vars, appType)	
	# print "Creating web.xml ..."
	createTopLevelWebXML(vars)	
	# print "Creating build.xml ..."
	createTopLevelBuildXML(vars)
	# print "Creating build.properties ..."
	createTopLevelBuildProperties(vars)
	# print "Creating env.properties ..."
	createTopLevelEnvProperties(vars)
	# print "Creating Eclipse-specific files ..."
	createTopLevelEclipseFiles(vars)
	# print "Creating READMEs ..."
	createTopLevelREADMEs(targetDir)

	createTestLevelDirectories(vars)
	createTestLevelREADMEs(targetDir)
	createTestLevelSipXML(vars, appType)	
	createTestLevelWebXML(vars)	
	createTestLevelBuildXML(vars)
	createTestLevelBuildProperties(vars)
	# not creating test level eclipse files since i'm not sure what
	# should go in them yet
	# createTestLevelEclipseFiles(vars)
	createTestLevelEnvProperties(vars)
	createTestLevelLog4jProperties(vars)
	createTestLevelTestProperties(vars)
	createTestSkeleton(vars)
	createTestRunner(vars)

	print
	print "APPLICATION CREATED in %s directory" % appName

def printUsage():
	print """
Creates a skeleton SIP ECharts application directory structure
e.g. directories, build files and skeleton SIP ECharts machine. The
command receives as parameters the information required to create the
directory structure e.g. the application name and the machine class
name.  The directory structure is created into the directory indicated by target_Directory parameter.


usage: telcoblocks_appgen [target_Directory] [application_Type] [package_Name] [class_Name] [application_Title]

e.g: telcoblocks_appgen /home/telcoblocks/destiny b2bua com.germinus.telcoblocks.echarts.myMachine myMachine "My telco machine"

"""
# Check python version
#
if not versioncheck.versioncheck(min='2.2', max='2.6.99'):
	print "Unsupported version of python"
	print "Use a version between 2.2.x and 2.6.x"
	sys.exit(1)

if len(sys.argv) != 6:
	print len(sys.argv)
	printUsage()
	sys.exit(1)
	
# Check for presence of EDK_HOME environment variable
#
try:
	edk_home = os.environ['EDK_HOME']
except KeyError:
	edk_home = None

if edk_home == None:
	# Check if appgen running from DK bin directory
	binPath = os.path.dirname(os.path.abspath(sys.argv[0]))
	edkPath = os.path.dirname(binPath)
	essSrcPath = string.replace("src/org/echarts/servlet/sip", "/", os.sep)
	if os.path.exists(edkPath + os.sep + essSrcPath):
		edk_home = edkPath

if edk_home == None:
	print """
*******
WARNING - Environment variable EDK_HOME is not set and appgen not
running from inside an EDK.  As a result, the ECharts Development Kit
will not be checked for classname collisions with your generated
class.  For best results, set the EDK_HOME variable before running
this program.
*******
"""

appgen_home = os.path.dirname(os.path.abspath(sys.argv[0]))

createSourceTree(**getNamesFromUser(edk_home))

